package ring

import (
	"fmt"
	"sync"
)

type Buffer struct {

	lock sync.Mutex

	buf []byte

	head int
	tail int

	cap int
	length int
}

func New(cap int) *Buffer {

	return &Buffer{
		buf: make([]byte, cap),
		head: 0,
		tail: 0,
		cap: cap,
	}
}

func (b *Buffer) GetHead(offset int) (d byte, err error) {
	if b.Size() <= offset {
		err = fmt.Errorf("out of length")
	}
	d = b.buf[(b.head + offset) % b.cap]
	return
}

func (b * Buffer) GetBuf() (buf []byte) {

	return
}

// 取出head位置内容 1. d<-head, 2. head move next
// err if empty
func (b *Buffer) Pick() (d byte, err error) {

	if b.Empty() {
		err = fmt.Errorf("empty")
		return
	}
	d = b.buf[b.head]
	b.sizeDec()
	if b.Size() > 0 {// buffer 为空的时候head==tail // length为1的时候head==tail
		b.headMove()
	}
	return
}

// 添加 到 当前 tail的下一个位置 1. tail move next , 2. tail<-d
// err if full
func (b *Buffer) Offer(d byte) (err error) {

	if b.Full() {
		err = fmt.Errorf("full")
		return
	}
	if b.Size() > 0 {
		b.tailMove()
	}
	b.buf[b.tail] = d
	b.sizeInc()
	return
}

// 内容长度
func (b *Buffer) Size() int {
	return b.length
}

func (b *Buffer) sizeInc() {
	b.lock.Lock()
	defer b.lock.Unlock()
	b.length++
}

func (b *Buffer) sizeDec() {
	b.lock.Lock()
	defer b.lock.Unlock()
	b.length--
}

func (b *Buffer) Empty() bool {
	return b.length == 0
}

func (b *Buffer) Full() bool {
	return b.length >= b.cap
}

func (b *Buffer) headMove() {
	b.head = (b.head+1+b.cap)%b.cap
}
func (b *Buffer) tailMove() {
	b.tail = (b.tail+1+b.cap)%b.cap
}